package cn.bxshey.activity.service.impl;

import cn.bxshey.activity.dto.AddActivityDTO;
import cn.bxshey.activity.service.ActivityService;
import cn.bxshey.general.entity.Activity;
import cn.bxshey.general.entity.Coupons;
import cn.bxshey.general.enums.ResultEnum;
import cn.bxshey.general.exception.BusinessException;
import cn.bxshey.redis.constant.RedisConstant;
import cn.bxshey.redis.utils.RedisUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @作者：不想说话而已
 * @Date：2024/3/3 15:11
 */
@Service
@Transactional
public class ActivityServiceImpl implements ActivityService {

    @Resource
    RedisUtils redisUtils;


    /**
     * 活动参加
     *
     * @param id         用户id
     * @param activityId 活动唯一标识
     * @return 优惠卷ID
     */
    @Override
    public String eventParticipation(Long id, String activityId) {

        //获取活动信息
        Set<String> setValue = redisUtils.getSetValue(RedisConstant.ACTIVITY, activityId);

        //活动不存在抛出异常，返回错误信息
        Optional.ofNullable(setValue).orElseThrow(() -> new BusinessException(ResultEnum.ERROR_ACTIVITY_NO));

        //用户是否已参与活动,参与抛出异常
        Set<String> participate = redisUtils.getSetValue(RedisConstant.ACTIVITY_USER, activityId);
        Optional.ofNullable(participate).ifPresent(p -> {
            participate.forEach(s -> {
                if (s.equals(String.valueOf(id))) {
                    throw new BusinessException(ResultEnum.ERROR_ACTIVITY_PARTICIPATE);
                }
            });
        });

        //对活动信息进行处理
        try {
//            redisUtils.addSetValue(RedisConstant.ACTIVITY, activityId);
            return activityFlow(setValue, id, activityId);
        } catch (Exception e) {
            throw new BusinessException(ResultEnum.ERROR_ACTIVITY, e);
        }
    }


    /**
     * 活动发布
     * @param id 发布者id
     * @param activity 活动信息
     * @return 活动ID
     */
    @Override
    public String eventPosting(Long id, AddActivityDTO activity) {
        //活动唯一标识id
        String activityId = UUID.randomUUID().toString();

        try {
            //新增活动
            redisUtils.addSetValue(RedisConstant.ACTIVITY,activityId,activity);
        } catch (JsonProcessingException e) {
            throw new BusinessException(ResultEnum.ERROR_ACTIVITY);
        }

        return activityId;
    }



    /**
     * 活动进行具体业务
     *
     * @param setValue   活动信息
     * @param id         用户id
     * @param activityId 活动唯一标识
     * @return 优惠卷ID
     */
    @Override
    public String activityFlow(Set<String> setValue, Long id, String activityId) {
        Coupons coupons = new Coupons();

        //优惠卷ID
        String couponsId = UUID.randomUUID().toString();

        //反序列化器
        ObjectMapper objectMapper = new ObjectMapper();

        List<String> list = new ArrayList<>(setValue);
        String activityStr = list.get(0);

        //对活动信息进行处理
            try {
                //获取活动详细信息
                Activity activity = objectMapper.readValue(activityStr, new TypeReference<Activity>() {
                });

                //优惠卷id
                coupons.setCouponsId(couponsId);

                //优惠卷结束时间
                //获取活动规则信息
                String[] split = activity.getActivityRules().split("%");
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.DAY_OF_YEAR, Integer.parseInt(split[0]));
                coupons.setCouponsEndTime(calendar.getTime());

                //优惠卷规则描述
                coupons.setCouponsRules(activity.getActivityRules());

                //优惠卷类型
                coupons.setCouponsTypeId(activity.getCouponsTypeId());

                //用户新增优惠卷
//                couponsMapper.addCoupons(coupons);

                //记录用户已参与此次活动
                redisUtils.addSetValue(RedisConstant.ACTIVITY_USER.concat(activityId), id);

                //更新用户持有优惠卷
                redisUtils.addSetValue(RedisConstant.COUPONS_USER, id, coupons.getCouponsId(), split[1], Long.parseLong(split[0]));


            } catch (JsonProcessingException e) {
                throw new BusinessException(ResultEnum.ERROR_ACTIVITY, e);
            }
        return couponsId;
    }

}
